<!DOCTYPE html>
<html lang="" xml:lang="">
<head>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Chapter 12 Discover | JavaScript for R</title>
  <meta name="description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="generator" content="bookdown 0.20 and GitBook 2.6.7" />

  <meta property="og:title" content="Chapter 12 Discover | JavaScript for R" />
  <meta property="og:type" content="book" />
  
  
  <meta property="og:description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="github-repo" content="JohnCoene/javascript-for-r" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="Chapter 12 Discover | JavaScript for R" />
  
  <meta name="twitter:description" content="Invite JavaScript into your Data Science workflow." />
  

<meta name="author" content="John Coene" />


<meta name="date" content="2020-08-23" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  
  
<link rel="prev" href="excercise-ploty.html"/>
<link rel="next" href="a-complete-integration.html"/>
<script src="libs/header-attrs/header-attrs.js"></script>
<script src="libs/jquery/jquery.min.js"></script>
<link href="libs/gitbook/css/style.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-fontsettings.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-clipboard.css" rel="stylesheet" />









<script src="libs/accessible-code-block/empty-anchor.js"></script>
<script src="libs/htmlwidgets/htmlwidgets.js"></script>
<script src="libs/plotly-binding/plotly.js"></script>
<script src="libs/typedarray/typedarray.min.js"></script>
<link href="libs/crosstalk/css/crosstalk.css" rel="stylesheet" />
<script src="libs/crosstalk/js/crosstalk.min.js"></script>
<link href="libs/plotly-htmlwidgets-css/plotly-htmlwidgets.css" rel="stylesheet" />
<script src="libs/plotly-main/plotly-latest.min.js"></script>
<script src="libs/core-js/shim.min.js"></script>
<script src="libs/react/react.min.js"></script>
<script src="libs/react/react-dom.min.js"></script>
<script src="libs/reactwidget/react-tools.js"></script>
<script src="libs/reactable-binding/reactable.js"></script>
<script src="libs/r2d3-render/r2d3-render.js"></script>
<script src="libs/webcomponents/webcomponents.js"></script>
<script src="libs/r2d3-binding/r2d3.js"></script>
<script src="libs/d3v5/d3.min.js"></script>
<script src="libs/viz/viz.js"></script>
<link href="libs/DiagrammeR-styles/styles.css" rel="stylesheet" />
<script src="libs/grViz-binding/grViz.js"></script>


<style type="text/css">
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {   }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>

<link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/toc.css" type="text/css" />
</head>

<body>



  <div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">

    <div class="book-summary">
      <nav role="navigation">

<ul class="summary">
<li><a href="./">JavaScript for R</a></li>

<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>Preface</a>
<ul>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#premise"><i class="fa fa-check"></i>Premise</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#book-structure"><i class="fa fa-check"></i>Book Structure</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#acknowledgement"><i class="fa fa-check"></i>Acknowledgement</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#disclaimer"><i class="fa fa-check"></i>Disclaimer</a></li>
</ul></li>
<li class="part"><span><b>I Basics &amp; Roadmap</b></span></li>
<li class="chapter" data-level="1" data-path="introduction.html"><a href="introduction.html"><i class="fa fa-check"></i><b>1</b> Introduction</a>
<ul>
<li class="chapter" data-level="1.1" data-path="introduction.html"><a href="introduction.html#rationale"><i class="fa fa-check"></i><b>1.1</b> Rationale</a></li>
<li class="chapter" data-level="1.2" data-path="introduction.html"><a href="introduction.html#methods"><i class="fa fa-check"></i><b>1.2</b> Methods</a>
<ul>
<li class="chapter" data-level="1.2.1" data-path="introduction.html"><a href="introduction.html#v8"><i class="fa fa-check"></i><b>1.2.1</b> V8</a></li>
<li class="chapter" data-level="1.2.2" data-path="introduction.html"><a href="introduction.html#htmlwidgets"><i class="fa fa-check"></i><b>1.2.2</b> htmlwidgets</a></li>
<li class="chapter" data-level="1.2.3" data-path="introduction.html"><a href="introduction.html#shiny"><i class="fa fa-check"></i><b>1.2.3</b> Shiny</a></li>
<li class="chapter" data-level="1.2.4" data-path="introduction.html"><a href="introduction.html#bubble"><i class="fa fa-check"></i><b>1.2.4</b> bubble</a></li>
</ul></li>
<li class="chapter" data-level="1.3" data-path="introduction.html"><a href="introduction.html#methods-amiss"><i class="fa fa-check"></i><b>1.3</b> Methods Amiss</a>
<ul>
<li class="chapter" data-level="1.3.1" data-path="introduction.html"><a href="introduction.html#reactr"><i class="fa fa-check"></i><b>1.3.1</b> reactR</a></li>
<li class="chapter" data-level="1.3.2" data-path="introduction.html"><a href="introduction.html#r2d3"><i class="fa fa-check"></i><b>1.3.2</b> r2d3</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="2" data-path="prerequisites.html"><a href="prerequisites.html"><i class="fa fa-check"></i><b>2</b> Prerequisites</a>
<ul>
<li class="chapter" data-level="2.1" data-path="prerequisites.html"><a href="prerequisites.html#r-package-development"><i class="fa fa-check"></i><b>2.1</b> R Package Development</a>
<ul>
<li class="chapter" data-level="2.1.1" data-path="prerequisites.html"><a href="prerequisites.html#creating-a-package"><i class="fa fa-check"></i><b>2.1.1</b> Creating a Package</a></li>
<li class="chapter" data-level="2.1.2" data-path="prerequisites.html"><a href="prerequisites.html#metadata"><i class="fa fa-check"></i><b>2.1.2</b> Metadata</a></li>
<li class="chapter" data-level="2.1.3" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>2.1.3</b> R code</a></li>
<li class="chapter" data-level="2.1.4" data-path="prerequisites.html"><a href="prerequisites.html#documentation"><i class="fa fa-check"></i><b>2.1.4</b> Documentation</a></li>
<li class="chapter" data-level="2.1.5" data-path="prerequisites.html"><a href="prerequisites.html#installed-files"><i class="fa fa-check"></i><b>2.1.5</b> Installed files</a></li>
<li class="chapter" data-level="2.1.6" data-path="prerequisites.html"><a href="prerequisites.html#build-load-and-install"><i class="fa fa-check"></i><b>2.1.6</b> Build, load, and install</a></li>
</ul></li>
<li class="chapter" data-level="2.2" data-path="prerequisites.html"><a href="prerequisites.html#json"><i class="fa fa-check"></i><b>2.2</b> JSON</a>
<ul>
<li class="chapter" data-level="2.2.1" data-path="prerequisites.html"><a href="prerequisites.html#serialising"><i class="fa fa-check"></i><b>2.2.1</b> Serialising</a></li>
<li class="chapter" data-level="2.2.2" data-path="prerequisites.html"><a href="prerequisites.html#tabular-data"><i class="fa fa-check"></i><b>2.2.2</b> Tabular data</a></li>
</ul></li>
<li class="chapter" data-level="2.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>2.3</b> JavaScript</a>
<ul>
<li class="chapter" data-level="2.3.1" data-path="prerequisites.html"><a href="prerequisites.html#developer-tools"><i class="fa fa-check"></i><b>2.3.1</b> Developer tools</a></li>
<li class="chapter" data-level="2.3.2" data-path="prerequisites.html"><a href="prerequisites.html#variable-declaration-and-scope"><i class="fa fa-check"></i><b>2.3.2</b> Variable declaration and scope</a></li>
<li class="chapter" data-level="2.3.3" data-path="prerequisites.html"><a href="prerequisites.html#document-object-model"><i class="fa fa-check"></i><b>2.3.3</b> Document object model</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>II Data Visualisation</b></span></li>
<li class="chapter" data-level="3" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html"><i class="fa fa-check"></i><b>3</b> Introduction to widgets</a>
<ul>
<li class="chapter" data-level="3.1" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html#plotly-package"><i class="fa fa-check"></i><b>3.1</b> Plotly package</a></li>
<li class="chapter" data-level="3.2" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html#dt-package"><i class="fa fa-check"></i><b>3.2</b> DT package</a></li>
</ul></li>
<li class="chapter" data-level="4" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html"><i class="fa fa-check"></i><b>4</b> Basics of building widgets</a>
<ul>
<li class="chapter" data-level="4.1" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#candidate-libraries"><i class="fa fa-check"></i><b>4.1</b> Candidate Libraries</a>
<ul>
<li class="chapter" data-level="4.1.1" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#plotly"><i class="fa fa-check"></i><b>4.1.1</b> Plotly</a></li>
<li class="chapter" data-level="4.1.2" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#highchart.js"><i class="fa fa-check"></i><b>4.1.2</b> Highchart.js</a></li>
<li class="chapter" data-level="4.1.3" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#chart.js"><i class="fa fa-check"></i><b>4.1.3</b> Chart.js</a></li>
</ul></li>
<li class="chapter" data-level="4.2" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#how-it-works"><i class="fa fa-check"></i><b>4.2</b> How it works</a></li>
</ul></li>
<li class="chapter" data-level="5" data-path="your-first-widget.html"><a href="your-first-widget.html"><i class="fa fa-check"></i><b>5</b> Your First Widget</a>
<ul>
<li class="chapter" data-level="5.1" data-path="your-first-widget.html"><a href="your-first-widget.html#the-scaffold"><i class="fa fa-check"></i><b>5.1</b> The Scaffold</a></li>
<li class="chapter" data-level="5.2" data-path="your-first-widget.html"><a href="your-first-widget.html#the-output"><i class="fa fa-check"></i><b>5.2</b> The Output</a></li>
<li class="chapter" data-level="5.3" data-path="your-first-widget.html"><a href="your-first-widget.html#javascript-side"><i class="fa fa-check"></i><b>5.3</b> JavaScript-side</a></li>
</ul></li>
<li class="chapter" data-level="6" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html"><i class="fa fa-check"></i><b>6</b> A Realistic Widget</a>
<ul>
<li class="chapter" data-level="6.1" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#dependency"><i class="fa fa-check"></i><b>6.1</b> Dependency</a></li>
<li class="chapter" data-level="6.2" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>6.2</b> JavaScript</a></li>
<li class="chapter" data-level="6.3" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#html-element"><i class="fa fa-check"></i><b>6.3</b> HTML Element</a></li>
</ul></li>
<li class="chapter" data-level="7" data-path="the-full-monty.html"><a href="the-full-monty.html"><i class="fa fa-check"></i><b>7</b> The Full Monty</a>
<ul>
<li class="chapter" data-level="7.1" data-path="the-full-monty.html"><a href="the-full-monty.html#dependencies"><i class="fa fa-check"></i><b>7.1</b> Dependencies</a></li>
<li class="chapter" data-level="7.2" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>7.2</b> JavaScript</a></li>
<li class="chapter" data-level="7.3" data-path="the-full-monty.html"><a href="the-full-monty.html#working-with-data"><i class="fa fa-check"></i><b>7.3</b> Working with Data</a></li>
<li class="chapter" data-level="7.4" data-path="the-full-monty.html"><a href="the-full-monty.html#transforming-data"><i class="fa fa-check"></i><b>7.4</b> Transforming Data</a>
<ul>
<li class="chapter" data-level="7.4.1" data-path="the-full-monty.html"><a href="the-full-monty.html#in-javascript"><i class="fa fa-check"></i><b>7.4.1</b> In JavaScript</a></li>
<li class="chapter" data-level="7.4.2" data-path="the-full-monty.html"><a href="the-full-monty.html#in-r"><i class="fa fa-check"></i><b>7.4.2</b> In R</a></li>
<li class="chapter" data-level="7.4.3" data-path="the-full-monty.html"><a href="the-full-monty.html#pros-cons"><i class="fa fa-check"></i><b>7.4.3</b> Pros &amp; Cons</a></li>
</ul></li>
<li class="chapter" data-level="7.5" data-path="the-full-monty.html"><a href="the-full-monty.html#on-print"><i class="fa fa-check"></i><b>7.5</b> On Print</a></li>
</ul></li>
<li class="chapter" data-level="8" data-path="advanced-topics.html"><a href="advanced-topics.html"><i class="fa fa-check"></i><b>8</b> Advanced Topics</a>
<ul>
<li class="chapter" data-level="8.1" data-path="advanced-topics.html"><a href="advanced-topics.html#shared-variables"><i class="fa fa-check"></i><b>8.1</b> Shared Variables</a>
<ul>
<li class="chapter" data-level="8.1.1" data-path="advanced-topics.html"><a href="advanced-topics.html#sizing"><i class="fa fa-check"></i><b>8.1.1</b> Sizing</a></li>
<li class="chapter" data-level="8.1.2" data-path="advanced-topics.html"><a href="advanced-topics.html#sizing-policy"><i class="fa fa-check"></i><b>8.1.2</b> Sizing Policy</a></li>
</ul></li>
<li class="chapter" data-level="8.2" data-path="advanced-topics.html"><a href="advanced-topics.html#resizing"><i class="fa fa-check"></i><b>8.2</b> Resizing</a></li>
<li class="chapter" data-level="8.3" data-path="advanced-topics.html"><a href="advanced-topics.html#pre-render-hooks-security"><i class="fa fa-check"></i><b>8.3</b> Pre Render Hooks &amp; Security</a></li>
<li class="chapter" data-level="8.4" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>8.4</b> JavaScript Code</a></li>
<li class="chapter" data-level="8.5" data-path="advanced-topics.html"><a href="advanced-topics.html#prepend-append-content"><i class="fa fa-check"></i><b>8.5</b> Prepend &amp; Append Content</a></li>
<li class="chapter" data-level="8.6" data-path="the-full-monty.html"><a href="the-full-monty.html#dependencies"><i class="fa fa-check"></i><b>8.6</b> Dependencies</a></li>
<li class="chapter" data-level="8.7" data-path="advanced-topics.html"><a href="advanced-topics.html#compatibility"><i class="fa fa-check"></i><b>8.7</b> Compatibility</a></li>
<li class="chapter" data-level="8.8" data-path="advanced-topics.html"><a href="advanced-topics.html#unit-tests"><i class="fa fa-check"></i><b>8.8</b> Unit Tests</a></li>
<li class="chapter" data-level="8.9" data-path="advanced-topics.html"><a href="advanced-topics.html#performances"><i class="fa fa-check"></i><b>8.9</b> Performances</a></li>
</ul></li>
<li class="chapter" data-level="9" data-path="crosstalk.html"><a href="crosstalk.html"><i class="fa fa-check"></i><b>9</b> Crosstalk</a>
<ul>
<li class="chapter" data-level="9.1" data-path="crosstalk.html"><a href="crosstalk.html#crosstalk-example"><i class="fa fa-check"></i><b>9.1</b> Crosstalk example</a></li>
<li class="chapter" data-level="9.2" data-path="crosstalk.html"><a href="crosstalk.html#crosstalk-requirements"><i class="fa fa-check"></i><b>9.2</b> Crosstalk requirements</a></li>
<li class="chapter" data-level="9.3" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#how-it-works"><i class="fa fa-check"></i><b>9.3</b> How it works</a></li>
<li class="chapter" data-level="9.4" data-path="crosstalk.html"><a href="crosstalk.html#crosstalk-with-gio"><i class="fa fa-check"></i><b>9.4</b> Crosstalk with gio</a></li>
<li class="chapter" data-level="9.5" data-path="crosstalk.html"><a href="crosstalk.html#adapt-the-r-code"><i class="fa fa-check"></i><b>9.5</b> Adapt the R code</a></li>
<li class="chapter" data-level="9.6" data-path="crosstalk.html"><a href="crosstalk.html#change-the-javascript-code"><i class="fa fa-check"></i><b>9.6</b> Change the JavaScript code</a>
<ul>
<li class="chapter" data-level="9.6.1" data-path="crosstalk.html"><a href="crosstalk.html#send-selected-keys"><i class="fa fa-check"></i><b>9.6.1</b> Send selected keys</a></li>
<li class="chapter" data-level="9.6.2" data-path="crosstalk.html"><a href="crosstalk.html#set-selected-keys"><i class="fa fa-check"></i><b>9.6.2</b> Set selected keys</a></li>
<li class="chapter" data-level="9.6.3" data-path="crosstalk.html"><a href="crosstalk.html#using-crosstalk-with-gio"><i class="fa fa-check"></i><b>9.6.3</b> Using crosstalk with gio</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="10" data-path="final-revisions.html"><a href="final-revisions.html"><i class="fa fa-check"></i><b>10</b> Final Revisions</a>
<ul>
<li class="chapter" data-level="10.1" data-path="the-full-monty.html"><a href="the-full-monty.html#working-with-data"><i class="fa fa-check"></i><b>10.1</b> Working with data</a></li>
<li class="chapter" data-level="10.2" data-path="final-revisions.html"><a href="final-revisions.html#plethora-of-options"><i class="fa fa-check"></i><b>10.2</b> Plethora of options</a></li>
<li class="chapter" data-level="10.3" data-path="final-revisions.html"><a href="final-revisions.html#interface-design"><i class="fa fa-check"></i><b>10.3</b> Interface design</a></li>
</ul></li>
<li class="chapter" data-level="11" data-path="excercise-ploty.html"><a href="excercise-ploty.html"><i class="fa fa-check"></i><b>11</b> Excercise - Ploty</a>
<ul>
<li class="chapter" data-level="11.1" data-path="excercise-ploty.html"><a href="excercise-ploty.html#discover-plotly"><i class="fa fa-check"></i><b>11.1</b> Discover Plotly</a></li>
<li class="chapter" data-level="11.2" data-path="excercise-ploty.html"><a href="excercise-ploty.html#basics-of-plotly"><i class="fa fa-check"></i><b>11.2</b> Basics of plotly</a></li>
<li class="chapter" data-level="11.3" data-path="excercise-ploty.html"><a href="excercise-ploty.html#javascript-to-r"><i class="fa fa-check"></i><b>11.3</b> JavaScript to R</a></li>
<li class="chapter" data-level="11.4" data-path="excercise-ploty.html"><a href="excercise-ploty.html#r-to-javascript"><i class="fa fa-check"></i><b>11.4</b> R to JavaScript</a></li>
<li class="chapter" data-level="11.5" data-path="excercise-ploty.html"><a href="excercise-ploty.html#size-resize"><i class="fa fa-check"></i><b>11.5</b> Size &amp; Resize</a></li>
<li class="chapter" data-level="11.6" data-path="excercise-ploty.html"><a href="excercise-ploty.html#performance-security"><i class="fa fa-check"></i><b>11.6</b> Performance &amp; Security</a></li>
</ul></li>
<li class="part"><span><b>III Web Development with Shiny</b></span></li>
<li class="chapter" data-level="12" data-path="discover.html"><a href="discover.html"><i class="fa fa-check"></i><b>12</b> Discover</a>
<ul>
<li class="chapter" data-level="12.1" data-path="discover.html"><a href="discover.html#static-files"><i class="fa fa-check"></i><b>12.1</b> Static Files</a></li>
<li class="chapter" data-level="12.2" data-path="discover.html"><a href="discover.html#example---alerts"><i class="fa fa-check"></i><b>12.2</b> Example - Alerts</a></li>
<li class="chapter" data-level="12.3" data-path="discover.html"><a href="discover.html#from-r-to-javascript"><i class="fa fa-check"></i><b>12.3</b> From R to JavaScript</a></li>
<li class="chapter" data-level="12.4" data-path="discover.html"><a href="discover.html#from-javascript-to-r"><i class="fa fa-check"></i><b>12.4</b> From JavaScript to R</a></li>
<li class="chapter" data-level="12.5" data-path="discover.html"><a href="discover.html#deserialise"><i class="fa fa-check"></i><b>12.5</b> Deserialise</a></li>
</ul></li>
<li class="chapter" data-level="13" data-path="a-complete-integration.html"><a href="a-complete-integration.html"><i class="fa fa-check"></i><b>13</b> A Complete Integration</a>
<ul>
<li class="chapter" data-level="13.1" data-path="a-complete-integration.html"><a href="a-complete-integration.html#serialisation"><i class="fa fa-check"></i><b>13.1</b> Serialisation</a></li>
<li class="chapter" data-level="13.2" data-path="a-complete-integration.html"><a href="a-complete-integration.html#events-callbacks"><i class="fa fa-check"></i><b>13.2</b> Events &amp; Callbacks</a></li>
<li class="chapter" data-level="13.3" data-path="a-complete-integration.html"><a href="a-complete-integration.html#as-a-package"><i class="fa fa-check"></i><b>13.3</b> As a Package</a>
<ul>
<li class="chapter" data-level="13.3.1" data-path="the-full-monty.html"><a href="the-full-monty.html#dependencies"><i class="fa fa-check"></i><b>13.3.1</b> Dependencies</a></li>
<li class="chapter" data-level="13.3.2" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>13.3.2</b> R Code</a></li>
<li class="chapter" data-level="13.3.3" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>13.3.3</b> JavaScript Code</a></li>
<li class="chapter" data-level="13.3.4" data-path="a-complete-integration.html"><a href="a-complete-integration.html#input-handler"><i class="fa fa-check"></i><b>13.3.4</b> Input Handler</a></li>
<li class="chapter" data-level="13.3.5" data-path="a-complete-integration.html"><a href="a-complete-integration.html#wrapping-up"><i class="fa fa-check"></i><b>13.3.5</b> Wrapping up</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="14" data-path="tips-tricks.html"><a href="tips-tricks.html"><i class="fa fa-check"></i><b>14</b> Tips &amp; Tricks</a>
<ul>
<li class="chapter" data-level="14.1" data-path="tips-tricks.html"><a href="tips-tricks.html#shiny-events"><i class="fa fa-check"></i><b>14.1</b> Shiny Events</a></li>
<li class="chapter" data-level="14.2" data-path="tips-tricks.html"><a href="tips-tricks.html#table-buttons"><i class="fa fa-check"></i><b>14.2</b> Table Buttons</a></li>
<li class="chapter" data-level="14.3" data-path="tips-tricks.html"><a href="tips-tricks.html#jquery---toggle"><i class="fa fa-check"></i><b>14.3</b> jQuery - Toggle</a></li>
</ul></li>
<li class="chapter" data-level="15" data-path="custom-outputs.html"><a href="custom-outputs.html"><i class="fa fa-check"></i><b>15</b> Custom Outputs</a>
<ul>
<li class="chapter" data-level="15.1" data-path="custom-outputs.html"><a href="custom-outputs.html#custom-outputs-inner-workings"><i class="fa fa-check"></i><b>15.1</b> Custom outputs inner-workings</a></li>
<li class="chapter" data-level="15.2" data-path="custom-outputs.html"><a href="custom-outputs.html#setup"><i class="fa fa-check"></i><b>15.2</b> Setup</a></li>
<li class="chapter" data-level="15.3" data-path="custom-outputs.html"><a href="custom-outputs.html#r-function"><i class="fa fa-check"></i><b>15.3</b> R function</a></li>
<li class="chapter" data-level="15.4" data-path="custom-outputs.html"><a href="custom-outputs.html#output"><i class="fa fa-check"></i><b>15.4</b> Output</a></li>
<li class="chapter" data-level="15.5" data-path="custom-outputs.html"><a href="custom-outputs.html#render"><i class="fa fa-check"></i><b>15.5</b> Render</a></li>
<li class="chapter" data-level="15.6" data-path="custom-outputs.html"><a href="custom-outputs.html#javascript-output-binding"><i class="fa fa-check"></i><b>15.6</b> JavaScript output binding</a>
<ul>
<li class="chapter" data-level="15.6.1" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-title"><i class="fa fa-check"></i><b>15.6.1</b> Boxxy title</a></li>
<li class="chapter" data-level="15.6.2" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-value"><i class="fa fa-check"></i><b>15.6.2</b> Boxxy value</a></li>
</ul></li>
<li class="chapter" data-level="15.7" data-path="custom-outputs.html"><a href="custom-outputs.html#background-color"><i class="fa fa-check"></i><b>15.7</b> Background color</a>
<ul>
<li class="chapter" data-level="15.7.1" data-path="custom-outputs.html"><a href="custom-outputs.html#register-the-output-binding"><i class="fa fa-check"></i><b>15.7.1</b> Register the output binding</a></li>
</ul></li>
<li class="chapter" data-level="15.8" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-usage"><i class="fa fa-check"></i><b>15.8</b> Boxxy usage</a></li>
</ul></li>
<li class="chapter" data-level="16" data-path="cookies.html"><a href="cookies.html"><i class="fa fa-check"></i><b>16</b> Cookies</a>
<ul>
<li class="chapter" data-level="16.1" data-path="cookies.html"><a href="cookies.html#discover-js-cookie"><i class="fa fa-check"></i><b>16.1</b> Discover js-cookie</a></li>
<li class="chapter" data-level="16.2" data-path="custom-outputs.html"><a href="custom-outputs.html#setup"><i class="fa fa-check"></i><b>16.2</b> Setup</a></li>
<li class="chapter" data-level="16.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>16.3</b> JavaScript</a></li>
<li class="chapter" data-level="16.4" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>16.4</b> R Code</a></li>
</ul></li>
<li class="chapter" data-level="17" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html"><i class="fa fa-check"></i><b>17</b> Widgets with Shiny</a>
<ul>
<li class="chapter" data-level="17.1" data-path="excercise-ploty.html"><a href="excercise-ploty.html#javascript-to-r"><i class="fa fa-check"></i><b>17.1</b> JavaScript to R</a></li>
<li class="chapter" data-level="17.2" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#input-handlers-for-widgets"><i class="fa fa-check"></i><b>17.2</b> Input handlers for widgets</a></li>
<li class="chapter" data-level="17.3" data-path="excercise-ploty.html"><a href="excercise-ploty.html#r-to-javascript"><i class="fa fa-check"></i><b>17.3</b> R to JavaScript</a>
<ul>
<li class="chapter" data-level="17.3.1" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#send-data"><i class="fa fa-check"></i><b>17.3.1</b> Send Data</a></li>
<li class="chapter" data-level="17.3.2" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#retrieve-widget-instance"><i class="fa fa-check"></i><b>17.3.2</b> Retrieve Widget Instance</a></li>
<li class="chapter" data-level="17.3.3" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#handle-data"><i class="fa fa-check"></i><b>17.3.3</b> Handle Data</a></li>
</ul></li>
<li class="chapter" data-level="17.4" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#proxy-function"><i class="fa fa-check"></i><b>17.4</b> Proxy Function</a></li>
<li class="chapter" data-level="17.5" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#clear-data"><i class="fa fa-check"></i><b>17.5</b> Clear Data</a></li>
<li class="chapter" data-level="17.6" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#update"><i class="fa fa-check"></i><b>17.6</b> Update</a></li>
</ul></li>
<li class="part"><span><b>IV JavaScript for Computations</b></span></li>
<li class="chapter" data-level="18" data-path="the-v8-engine.html"><a href="the-v8-engine.html"><i class="fa fa-check"></i><b>18</b> The V8 Engine</a>
<ul>
<li class="chapter" data-level="18.1" data-path="the-v8-engine.html"><a href="the-v8-engine.html#installation"><i class="fa fa-check"></i><b>18.1</b> Installation</a></li>
<li class="chapter" data-level="18.2" data-path="the-v8-engine.html"><a href="the-v8-engine.html#basics"><i class="fa fa-check"></i><b>18.2</b> Basics</a></li>
<li class="chapter" data-level="18.3" data-path="the-v8-engine.html"><a href="the-v8-engine.html#external-libraries"><i class="fa fa-check"></i><b>18.3</b> External Libraries</a></li>
<li class="chapter" data-level="18.4" data-path="the-v8-engine.html"><a href="the-v8-engine.html#with-npm"><i class="fa fa-check"></i><b>18.4</b> With Npm</a></li>
<li class="chapter" data-level="18.5" data-path="the-v8-engine.html"><a href="the-v8-engine.html#use-in-packages"><i class="fa fa-check"></i><b>18.5</b> Use in Packages</a></li>
</ul></li>
<li class="part"><span><b>V Examples</b></span></li>
<li class="chapter" data-level="19" data-path="image-classifier.html"><a href="image-classifier.html"><i class="fa fa-check"></i><b>19</b> Image Classifier</a>
<ul>
<li class="chapter" data-level="19.1" data-path="discover.html"><a href="discover.html#discover"><i class="fa fa-check"></i><b>19.1</b> Discover</a></li>
<li class="chapter" data-level="19.2" data-path="custom-outputs.html"><a href="custom-outputs.html#setup"><i class="fa fa-check"></i><b>19.2</b> Setup</a></li>
<li class="chapter" data-level="19.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>19.3</b> JavaScript</a></li>
<li class="chapter" data-level="19.4" data-path="a-complete-integration.html"><a href="a-complete-integration.html#input-handler"><i class="fa fa-check"></i><b>19.4</b> Input Handler</a></li>
</ul></li>
<li class="chapter" data-level="20" data-path="progress-bar.html"><a href="progress-bar.html"><i class="fa fa-check"></i><b>20</b> Progress Bar</a>
<ul>
<li class="chapter" data-level="20.1" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>20.1</b> R code</a></li>
<li class="chapter" data-level="20.2" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>20.2</b> JavaScript code</a></li>
<li class="chapter" data-level="20.3" data-path="progress-bar.html"><a href="progress-bar.html#events"><i class="fa fa-check"></i><b>20.3</b> Events</a></li>
</ul></li>
<li class="chapter" data-level="21" data-path="machine-learning.html"><a href="machine-learning.html"><i class="fa fa-check"></i><b>21</b> Machine Learning</a>
<ul>
<li class="chapter" data-level="21.1" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#dependency"><i class="fa fa-check"></i><b>21.1</b> Dependency</a></li>
<li class="chapter" data-level="21.2" data-path="machine-learning.html"><a href="machine-learning.html#simple-regression"><i class="fa fa-check"></i><b>21.2</b> Simple Regression</a></li>
</ul></li>
<li class="part"><span><b>VI Closing Remarks</b></span></li>
<li class="chapter" data-level="22" data-path="conclusion.html"><a href="conclusion.html"><i class="fa fa-check"></i><b>22</b> Conclusion</a>
<ul>
<li class="chapter" data-level="22.1" data-path="advanced-topics.html"><a href="advanced-topics.html#performances"><i class="fa fa-check"></i><b>22.1</b> Performances</a></li>
<li class="chapter" data-level="22.2" data-path="conclusion.html"><a href="conclusion.html#road-ahead"><i class="fa fa-check"></i><b>22.2</b> Road ahead</a>
<ul>
<li class="chapter" data-level="22.2.1" data-path="conclusion.html"><a href="conclusion.html#computation"><i class="fa fa-check"></i><b>22.2.1</b> Computation</a></li>
<li class="chapter" data-level="22.2.2" data-path="introduction.html"><a href="introduction.html#shiny"><i class="fa fa-check"></i><b>22.2.2</b> Shiny</a></li>
<li class="chapter" data-level="22.2.3" data-path="introduction.html"><a href="introduction.html#htmlwidgets"><i class="fa fa-check"></i><b>22.2.3</b> htmlwidgets</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="" data-path="references.html"><a href="references.html"><i class="fa fa-check"></i>References</a></li>
</ul>

      </nav>
    </div>

    <div class="book-body">
      <div class="body-inner">
        <div class="book-header" role="navigation">
          <h1>
            <i class="fa fa-circle-o-notch fa-spin"></i><a href="./">JavaScript for R</a>
          </h1>
        </div>

        <div class="page-wrapper" tabindex="-1" role="main">
          <div class="page-inner">

            <section class="normal" id="section-">
<div id="discover" class="section level1" number="12">
<h1><span class="header-section-number">Chapter 12</span> Discover</h1>
<p>Shiny is the web framework of choice for the R programming language. Since JavaScript and Shiny both run in web browsers it follows that they can run alongside one another as one can include JavaScript in such applications. Yet, often disregarded is the ability for Shiny’s R server to communicate to the front-end and vice versa. This collection of chapters aims to show precisely how this works. In this first part, we brush up on the essentials so we understand how to include JavaScript in shiny applications.</p>
<p>Then again, the goal is not to write a lot of convoluted JavaScript, on the contrary, with little knowledge of the language the aim is to write as little as possible but demonstrate to the reader that it is often enough to greatly improve the user experience of shiny applications.</p>
<div id="static-files" class="section level2" number="12.1">
<h2><span class="header-section-number">12.1</span> Static Files</h2>
<p>In order to introduce JavaScript to shiny applications one must understand static files and how they work with the framework. Static files are files that are downloaded by the clients, in this case web browsers accessing shiny applications, as-is, these generally include images, CSS (<code>.css</code>), and JavaScript (<code>.js</code>).</p>
<p>If you are familiar with R packags it enablesge development, static files are to shiny applications what the “inst” directory is to an R package, those files are installed as-is and do not require further processing as opposed to the “src” folder which contains files that need compiling for instance.</p>
<p>There are numerous functions to launch a shiny application locally; the two most used probably are <code>shinyApp</code> and <code>runApp</code>. The RStudio IDE comes with a convenient “Run” button when writing a shiny application, which when clicked actually uses the function <code>shiny::runApp</code> in the background, this function looks for said static files in the <code>www</code> directory and makes them available at the same path (<code>/www</code>). If you are building your applications outside of RStudio, you should either also use <code>shiny::runApp</code> or specify the directory which then allows using <code>shiny::shinyApp</code>. Note that this only applies locally, shiny server (community and pro) as well as <a href="https://www.shinyapps.io/">shinyapps.io</a> use the same defaults as the RStudio IDE and <code>shiny::runApp</code>.</p>
<p>In order to ensure the code in this book can run regardless of the reader’s machine or editor, the asset directory is always specified explicitly. This is probably advised to steer clear of the potential headaches as, unlike the default, it’ll work regardless of the environment. If you are using <a href="https://thinkr-open.github.io/golem/">golem</a> <span class="citation">(Guyader et al. <a href="#ref-R-golem" role="doc-biblioref">2020</a>)</span> to develop your application then you should not worry about this as it specifies the directory internally.</p>
<p>Below we build a basic shiny application, however, before we define the ui and server we use the <code>shiny::addResourcePath</code> function to specify the location of the directory of static files that will be served by the server and thus accessible by the client. This function takes two arguments, first the <code>prefix</code>, which is the path (URL) at which the assets will be available, second the path to the directory of static assets.</p>
<p>We thus create the “assets” directory and a JavaScript file called <code>script.js</code> within it.</p>
<div class="sourceCode" id="cb224"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb224-1"><a href="discover.html#cb224-1"></a><span class="co"># run from root of app (where app.R is located)</span></span>
<span id="cb224-2"><a href="discover.html#cb224-2"></a><span class="kw">dir.create</span>(<span class="st">&quot;assets&quot;</span>)</span>
<span id="cb224-3"><a href="discover.html#cb224-3"></a><span class="kw">writeLines</span>(<span class="st">&quot;console.log(&#39;Hello JS!&#39;);&quot;</span>, <span class="dt">con =</span> <span class="st">&quot;assets/script.js&quot;</span>)</span></code></pre></div>
<p>We can now use the <code>shiny::addResourcePath</code> to point to this directory. Generally the same name for the directory of static assets and prefix is used so as to avoid confusion, below we name them differently in order for the reader to clearly distinguish which is which.</p>
<div class="sourceCode" id="cb225"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb225-1"><a href="discover.html#cb225-1"></a><span class="co"># app.R</span></span>
<span id="cb225-2"><a href="discover.html#cb225-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb225-3"><a href="discover.html#cb225-3"></a></span>
<span id="cb225-4"><a href="discover.html#cb225-4"></a><span class="co"># serve the files</span></span>
<span id="cb225-5"><a href="discover.html#cb225-5"></a><span class="kw">addResourcePath</span>(</span>
<span id="cb225-6"><a href="discover.html#cb225-6"></a>  <span class="co"># will be accessible at /files</span></span>
<span id="cb225-7"><a href="discover.html#cb225-7"></a>  <span class="dt">prefix =</span> <span class="st">&quot;files&quot;</span>, </span>
<span id="cb225-8"><a href="discover.html#cb225-8"></a>  <span class="co"># path to the assets directory</span></span>
<span id="cb225-9"><a href="discover.html#cb225-9"></a>  <span class="dt">directoryPath =</span> <span class="st">&quot;assets&quot;</span></span>
<span id="cb225-10"><a href="discover.html#cb225-10"></a>)</span>
<span id="cb225-11"><a href="discover.html#cb225-11"></a></span>
<span id="cb225-12"><a href="discover.html#cb225-12"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb225-13"><a href="discover.html#cb225-13"></a>  <span class="kw">h1</span>(<span class="st">&quot;R and JavaScript&quot;</span>)</span>
<span id="cb225-14"><a href="discover.html#cb225-14"></a>)</span>
<span id="cb225-15"><a href="discover.html#cb225-15"></a></span>
<span id="cb225-16"><a href="discover.html#cb225-16"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output){}</span>
<span id="cb225-17"><a href="discover.html#cb225-17"></a></span>
<span id="cb225-18"><a href="discover.html#cb225-18"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>If you then run the application and open it at the <code>/files/script.js</code> path (e.g.: <code>127.0.0.1:3000/files/script.js</code>) you should see the content of the JavaScript file (<code>console.log('Hello JS!')</code>), commenting the <code>addResourcePath</code> line will have a “Not Found” error displayed on the page instead.</p>
<p>All files in your asset directory will be served online and accessible to anyone: do not place sensitive files in it.</p>
<p>Though one may create multiple such directory and correspondingly use <code>addResourcePath</code> to specify multiple paths and prefixes, one will routinely specify a single one, named “assets” or “static,” which contains multiple subdirectories, one for each type of static file to obtain a directory that looks something like the tree below. This is, however, an unwritten convention which is by no means forced upon the developer: do as you wish.</p>
<pre><code>assets/
├── js/
│    └── script.js
├── css/
│    └── style.css
└── img/
     └── pic.png</code></pre>
<p>At this stage we have made the JavaScript file we created accessible by the clients but we still have to source this file in the <code>ui</code> as currently this file is, though served, not used by the application. Were one creating a static HTML page one would use the <code>script</code> to <code>src</code> the file in the <code>head</code> of the page.</p>
<div class="sourceCode" id="cb227"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb227-1"><a href="discover.html#cb227-1"></a><span class="kw">&lt;html&gt;</span></span>
<span id="cb227-2"><a href="discover.html#cb227-2"></a>  <span class="kw">&lt;head&gt;</span></span>
<span id="cb227-3"><a href="discover.html#cb227-3"></a>    <span class="er">&lt;</span>!–– source the JavaScript file ––&gt;</span>
<span id="cb227-4"><a href="discover.html#cb227-4"></a>    <span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;path/to/script.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb227-5"><a href="discover.html#cb227-5"></a>  <span class="kw">&lt;/head&gt;</span></span>
<span id="cb227-6"><a href="discover.html#cb227-6"></a>  <span class="kw">&lt;body&gt;</span></span>
<span id="cb227-7"><a href="discover.html#cb227-7"></a>    <span class="kw">&lt;p</span><span class="ot"> id=</span><span class="st">&quot;content&quot;</span><span class="kw">&gt;</span>Trying JavaScript!<span class="kw">&lt;/p&gt;</span></span>
<span id="cb227-8"><a href="discover.html#cb227-8"></a>  <span class="kw">&lt;/body&gt;</span></span>
<span id="cb227-9"><a href="discover.html#cb227-9"></a><span class="kw">&lt;/html&gt;</span></span></code></pre></div>
<p>In shiny we write the ui in R and not in HTML (though this is also supported). Given the resemblance between the names of HTML tags and shiny UI functions it’s pretty straightforward, the html page above would look something like the shiny <code>ui</code> below.</p>
<div class="sourceCode" id="cb228"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb228-1"><a href="discover.html#cb228-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb228-2"><a href="discover.html#cb228-2"></a></span>
<span id="cb228-3"><a href="discover.html#cb228-3"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb228-4"><a href="discover.html#cb228-4"></a>  tags<span class="op">$</span><span class="kw">head</span>(</span>
<span id="cb228-5"><a href="discover.html#cb228-5"></a>    tags<span class="op">$</span><span class="kw">script</span>(<span class="dt">src =</span> <span class="st">&quot;path/to/script.js&quot;</span>)</span>
<span id="cb228-6"><a href="discover.html#cb228-6"></a>  ),</span>
<span id="cb228-7"><a href="discover.html#cb228-7"></a>  <span class="kw">p</span>(<span class="dt">id =</span> <span class="st">&quot;content&quot;</span>, <span class="st">&quot;Trying JavaScript!&quot;</span>)</span>
<span id="cb228-8"><a href="discover.html#cb228-8"></a>)</span></code></pre></div>
<p>Note that we use the <code>tags</code> object which comes from the shiny package and includes HTML tags that are not exported as standalone functions. For instance, you can create a <code>&lt;div&gt;</code> in shiny with the <code>div</code> function but <code>tags$div</code> will also work. This can now be applied to the shiny application, the <code>path/to/script.js</code> should be changed to <code>files/script.js</code> where <code>files</code> is the prefix we defined in <code>addResourcePath</code>.</p>
<div class="sourceCode" id="cb229"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb229-1"><a href="discover.html#cb229-1"></a><span class="co"># app.R</span></span>
<span id="cb229-2"><a href="discover.html#cb229-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb229-3"><a href="discover.html#cb229-3"></a></span>
<span id="cb229-4"><a href="discover.html#cb229-4"></a><span class="co"># serve the files</span></span>
<span id="cb229-5"><a href="discover.html#cb229-5"></a><span class="kw">addResourcePath</span>(<span class="dt">prefix =</span> <span class="st">&quot;files&quot;</span>, <span class="dt">directoryPath =</span> <span class="st">&quot;assets&quot;</span>)</span>
<span id="cb229-6"><a href="discover.html#cb229-6"></a></span>
<span id="cb229-7"><a href="discover.html#cb229-7"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb229-8"><a href="discover.html#cb229-8"></a>  tags<span class="op">$</span><span class="kw">head</span>(</span>
<span id="cb229-9"><a href="discover.html#cb229-9"></a>    tags<span class="op">$</span><span class="kw">script</span>(<span class="dt">src =</span> <span class="st">&quot;files/script.js&quot;</span>)</span>
<span id="cb229-10"><a href="discover.html#cb229-10"></a>  ),</span>
<span id="cb229-11"><a href="discover.html#cb229-11"></a>  <span class="kw">h1</span>(<span class="st">&quot;R and JavaScript&quot;</span>)</span>
<span id="cb229-12"><a href="discover.html#cb229-12"></a>)</span>
<span id="cb229-13"><a href="discover.html#cb229-13"></a></span>
<span id="cb229-14"><a href="discover.html#cb229-14"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output){}</span>
<span id="cb229-15"><a href="discover.html#cb229-15"></a></span>
<span id="cb229-16"><a href="discover.html#cb229-16"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>From the browser, inspecting page (right click &gt; inspect &gt; console tab) one should see “Hello JS!” in the console which means the application correctly ran the code in the JavaScript file.</p>
</div>
<div id="example---alerts" class="section level2" number="12.2">
<h2><span class="header-section-number">12.2</span> Example - Alerts</h2>
<p>Making shiny work with JavaScript can essentially be broken down into two operations: 1) passing data from the R server to the JavaScript client and 2) the other way around, from the client to the R server. This chapter covers both ways data travels between R and JavaScript in Shiny.</p>
<p>We first build an application that passes a message from the R server to the client to display said message as a vanilla JavaScript alert (pop-up), then send back to the R server whether the user has clicked “OK” on the alert. Let’s write a straightforward shiny application which includes the JavaScript code that opens an alert.</p>
<div class="sourceCode" id="cb230"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb230-1"><a href="discover.html#cb230-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb230-2"><a href="discover.html#cb230-2"></a></span>
<span id="cb230-3"><a href="discover.html#cb230-3"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb230-4"><a href="discover.html#cb230-4"></a>  tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb230-5"><a href="discover.html#cb230-5"></a>    <span class="st">&quot;alert(&#39;Hello from JavaScript&#39;);&quot;</span></span>
<span id="cb230-6"><a href="discover.html#cb230-6"></a>  ),</span>
<span id="cb230-7"><a href="discover.html#cb230-7"></a>  <span class="kw">h1</span>(<span class="st">&quot;Hello&quot;</span>)</span>
<span id="cb230-8"><a href="discover.html#cb230-8"></a>)</span>
<span id="cb230-9"><a href="discover.html#cb230-9"></a></span>
<span id="cb230-10"><a href="discover.html#cb230-10"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){}</span>
<span id="cb230-11"><a href="discover.html#cb230-11"></a></span>
<span id="cb230-12"><a href="discover.html#cb230-12"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<div class="figure">
<img src="images/alert.png" alt="" />
<p class="caption">JavaScript alert in shiny</p>
</div>
<p>One thing important to note for later is that alerts will always block the execution of code which allows making sure some code is only run with user consent or the user being aware of the consequences.</p>
<div class="sourceCode" id="cb231"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb231-1"><a href="discover.html#cb231-1"></a><span class="at">alert</span>(<span class="st">&#39;delete everything?&#39;</span>)<span class="op">;</span></span>
<span id="cb231-2"><a href="discover.html#cb231-2"></a><span class="at">deleteEverythingOnlyIfUserOK</span>()<span class="op">;</span></span></code></pre></div>
</div>
<div id="from-r-to-javascript" class="section level2" number="12.3">
<h2><span class="header-section-number">12.3</span> From R to JavaScript</h2>
<p>Now that we have a simple alert displayed in the application we can tie it with the R server; the alert should display a message sent by the R server, this would enable, for instance, displaying a message taken from a database or a user input. As might be expected there are two functions required to do so, an R function and its JavaScript complementary: one to send the data from the server and another to catch said data from the client and display the alert.</p>
<p>Let us start by writing the R code to send the data, thankfully very little is required of the developer. One can send data from the R server to the client from the <code>session</code> object using the <code>sendCustomMessage</code> method. The method takes two arguments, first an identifier (where to send the data to), second the actual data to send to JavaScript.</p>
<div class="sourceCode" id="cb232"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb232-1"><a href="discover.html#cb232-1"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){</span>
<span id="cb232-2"><a href="discover.html#cb232-2"></a>  <span class="co"># set the identifier to send-alert</span></span>
<span id="cb232-3"><a href="discover.html#cb232-3"></a>  session<span class="op">$</span><span class="kw">sendCustomMessage</span>(</span>
<span id="cb232-4"><a href="discover.html#cb232-4"></a>    <span class="dt">type =</span> <span class="st">&quot;send-alert&quot;</span>, <span class="dt">message =</span> <span class="st">&quot;Hi there!&quot;</span></span>
<span id="cb232-5"><a href="discover.html#cb232-5"></a>  )</span>
<span id="cb232-6"><a href="discover.html#cb232-6"></a>}</span></code></pre></div>
<p>This effectively sends the message to the JavaScript client but we are yet to use that message JavaScript-side so the application still displays the same alert on load. We can add a “handler” for the identifier we defined (<code>send-alert</code>) which will so something with the message we sent from the server. This is done with the <code>addCustomMessageHandler</code> method from the <code>Shiny</code> object where the first argument is the identifier and the second is the function that handles the message, a function that takes a single argument: the data sent from the server.</p>
<div class="sourceCode" id="cb233"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb233-1"><a href="discover.html#cb233-1"></a>tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb233-2"><a href="discover.html#cb233-2"></a>  <span class="st">&quot;Shiny.addCustomMessageHandler(</span></span>
<span id="cb233-3"><a href="discover.html#cb233-3"></a><span class="st">    type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb233-4"><a href="discover.html#cb233-4"></a><span class="st">      alert(message);</span></span>
<span id="cb233-5"><a href="discover.html#cb233-5"></a><span class="st">  });&quot;</span></span>
<span id="cb233-6"><a href="discover.html#cb233-6"></a>)</span></code></pre></div>
<div class="figure">
<img src="images/alert-shiny.png" alt="" />
<p class="caption">Alert sent from shiny server</p>
</div>
<p>This enables you to pass a message that is taken from a database for instance, or as shown below from a user input, to the alert.</p>
<div class="sourceCode" id="cb234"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb234-1"><a href="discover.html#cb234-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb234-2"><a href="discover.html#cb234-2"></a></span>
<span id="cb234-3"><a href="discover.html#cb234-3"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb234-4"><a href="discover.html#cb234-4"></a>  tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb234-5"><a href="discover.html#cb234-5"></a>    <span class="st">&quot;Shiny.addCustomMessageHandler(</span></span>
<span id="cb234-6"><a href="discover.html#cb234-6"></a><span class="st">      type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb234-7"><a href="discover.html#cb234-7"></a><span class="st">        alert(message);</span></span>
<span id="cb234-8"><a href="discover.html#cb234-8"></a><span class="st">    });&quot;</span></span>
<span id="cb234-9"><a href="discover.html#cb234-9"></a>  ),</span>
<span id="cb234-10"><a href="discover.html#cb234-10"></a>  <span class="kw">h1</span>(<span class="st">&quot;Hello&quot;</span>),</span>
<span id="cb234-11"><a href="discover.html#cb234-11"></a>  <span class="kw">textInput</span>(<span class="st">&quot;text&quot;</span>, <span class="st">&quot;Text to show in alert&quot;</span>),</span>
<span id="cb234-12"><a href="discover.html#cb234-12"></a>  <span class="kw">actionButton</span>(<span class="st">&quot;submit&quot;</span>, <span class="st">&quot;Show alert&quot;</span>)</span>
<span id="cb234-13"><a href="discover.html#cb234-13"></a>)</span>
<span id="cb234-14"><a href="discover.html#cb234-14"></a></span>
<span id="cb234-15"><a href="discover.html#cb234-15"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){</span>
<span id="cb234-16"><a href="discover.html#cb234-16"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>submit, {</span>
<span id="cb234-17"><a href="discover.html#cb234-17"></a>    session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="dt">type =</span> <span class="st">&quot;send-alert&quot;</span>, <span class="dt">message =</span> input<span class="op">$</span>text)</span>
<span id="cb234-18"><a href="discover.html#cb234-18"></a>  })</span>
<span id="cb234-19"><a href="discover.html#cb234-19"></a>}</span>
<span id="cb234-20"><a href="discover.html#cb234-20"></a></span>
<span id="cb234-21"><a href="discover.html#cb234-21"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>In the application above, notice the path that the message follows: it goes from the client to the server which sends it back to the client. This might be considered suboptimal by some as it is not necessary to use the server as intermediary (in this example at least). Though there is some truth to this the above will work perfectly fine—and the aim here is to make JavaScript work with R—not alongside it.</p>
</div>
<div id="from-javascript-to-r" class="section level2" number="12.4">
<h2><span class="header-section-number">12.4</span> From JavaScript to R</h2>
<p>Imagine if you will that instead of displaying a somewhat anodyne alert it was one that actually mattered where the user is warned that clicking “OK” will execute an irreversible action like the deletion of a record. In order to implement this the server would need to “know” whether the user has clicked said “OK” button. To do so one needs to pass data from the client to the server.</p>
<p>This can be done by defining a <em>simplified</em> shiny input. While one can define a fully-fledged shiny inputs that can be registered, updated, etc. there is also a simplified version of the latter which allows sending reactive input values to the server where it can be used just like any other inputs (<code>input$id</code>). The value of the input can be defined using the <code>setInputValue</code> method which takes the id of the input and the value to give it.</p>
<div class="sourceCode" id="cb235"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb235-1"><a href="discover.html#cb235-1"></a>tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb235-2"><a href="discover.html#cb235-2"></a>  <span class="st">&quot;Shiny.addCustomMessageHandler(</span></span>
<span id="cb235-3"><a href="discover.html#cb235-3"></a><span class="st">    type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb235-4"><a href="discover.html#cb235-4"></a><span class="st">    </span></span>
<span id="cb235-5"><a href="discover.html#cb235-5"></a><span class="st">      // show alert</span></span>
<span id="cb235-6"><a href="discover.html#cb235-6"></a><span class="st">      alert(message);</span></span>
<span id="cb235-7"><a href="discover.html#cb235-7"></a></span>
<span id="cb235-8"><a href="discover.html#cb235-8"></a><span class="st">      // set to true when clicked OK</span></span>
<span id="cb235-9"><a href="discover.html#cb235-9"></a><span class="st">      Shiny.setInputValue(&#39;delete_alert&#39;, true);</span></span>
<span id="cb235-10"><a href="discover.html#cb235-10"></a><span class="st">  });&quot;</span></span>
<span id="cb235-11"><a href="discover.html#cb235-11"></a>)</span></code></pre></div>
<p>As mentioned earlier <code>alert</code> blocks code execution, therefore the input value will not be defined before the button “OK” is pressed. The server can now access the <code>input$delete_alert</code> input which is by default <code>NULL</code> and set to <code>TRUE</code> when the user has pressed “OK,” as done in the application below which prints the input to the console when the button is clicked.</p>
<div class="sourceCode" id="cb236"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb236-1"><a href="discover.html#cb236-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb236-2"><a href="discover.html#cb236-2"></a></span>
<span id="cb236-3"><a href="discover.html#cb236-3"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb236-4"><a href="discover.html#cb236-4"></a>  tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb236-5"><a href="discover.html#cb236-5"></a>    <span class="st">&quot;Shiny.addCustomMessageHandler(</span></span>
<span id="cb236-6"><a href="discover.html#cb236-6"></a><span class="st">      type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb236-7"><a href="discover.html#cb236-7"></a><span class="st">        alert(message);</span></span>
<span id="cb236-8"><a href="discover.html#cb236-8"></a><span class="st">        Shiny.setInputValue(&#39;delete_alert&#39;, true);</span></span>
<span id="cb236-9"><a href="discover.html#cb236-9"></a><span class="st">    });&quot;</span></span>
<span id="cb236-10"><a href="discover.html#cb236-10"></a>  ),</span>
<span id="cb236-11"><a href="discover.html#cb236-11"></a>  <span class="kw">h1</span>(<span class="st">&quot;Hello&quot;</span>)</span>
<span id="cb236-12"><a href="discover.html#cb236-12"></a>)</span>
<span id="cb236-13"><a href="discover.html#cb236-13"></a></span>
<span id="cb236-14"><a href="discover.html#cb236-14"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){</span>
<span id="cb236-15"><a href="discover.html#cb236-15"></a>  session<span class="op">$</span><span class="kw">sendCustomMessage</span>(</span>
<span id="cb236-16"><a href="discover.html#cb236-16"></a>    <span class="dt">type =</span> <span class="st">&quot;send-alert&quot;</span>, <span class="dt">message =</span> <span class="st">&quot;Deleting a record!&quot;</span></span>
<span id="cb236-17"><a href="discover.html#cb236-17"></a>  )</span>
<span id="cb236-18"><a href="discover.html#cb236-18"></a></span>
<span id="cb236-19"><a href="discover.html#cb236-19"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>delete_alert, {</span>
<span id="cb236-20"><a href="discover.html#cb236-20"></a>    <span class="co"># print TRUE when button is clicked</span></span>
<span id="cb236-21"><a href="discover.html#cb236-21"></a>    <span class="kw">print</span>(input<span class="op">$</span>delete_alert) </span>
<span id="cb236-22"><a href="discover.html#cb236-22"></a>  })</span>
<span id="cb236-23"><a href="discover.html#cb236-23"></a>}</span>
<span id="cb236-24"><a href="discover.html#cb236-24"></a></span>
<span id="cb236-25"><a href="discover.html#cb236-25"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>Note that Shiny performs optimisations on how those values are set. First, if the input is set to the same value then Shiny ignores it. This is fine if you are interested in the actual value of the input but will not work as expected if the input is to be used as event. Indeed if you want to use this input in an <code>observe</code>, <code>observeEvent</code>, or <code>eventReactive</code>, you want it to be triggered every time the input changes, regardless of whether that value is the same as before. The second optimisation Shiny does is when the input is set to multiple different values before these have been processed then only the most recent value will actually be sent to the server. One can opt-out of these optimisations using the <code>priority: "event"</code> option when setting the input value.</p>
<div class="sourceCode" id="cb237"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb237-1"><a href="discover.html#cb237-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb237-2"><a href="discover.html#cb237-2"></a></span>
<span id="cb237-3"><a href="discover.html#cb237-3"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb237-4"><a href="discover.html#cb237-4"></a>  tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb237-5"><a href="discover.html#cb237-5"></a>    <span class="st">&quot;Shiny.addCustomMessageHandler(</span></span>
<span id="cb237-6"><a href="discover.html#cb237-6"></a><span class="st">      type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb237-7"><a href="discover.html#cb237-7"></a><span class="st">        alert(message);</span></span>
<span id="cb237-8"><a href="discover.html#cb237-8"></a><span class="st">        Shiny.setInputValue(&#39;delete_alert&#39;, true, {priority: &#39;event&#39;});</span></span>
<span id="cb237-9"><a href="discover.html#cb237-9"></a><span class="st">    });&quot;</span></span>
<span id="cb237-10"><a href="discover.html#cb237-10"></a>  ),</span>
<span id="cb237-11"><a href="discover.html#cb237-11"></a>  <span class="kw">h1</span>(<span class="st">&quot;Hello&quot;</span>)</span>
<span id="cb237-12"><a href="discover.html#cb237-12"></a>)</span>
<span id="cb237-13"><a href="discover.html#cb237-13"></a></span>
<span id="cb237-14"><a href="discover.html#cb237-14"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){</span>
<span id="cb237-15"><a href="discover.html#cb237-15"></a>  session<span class="op">$</span><span class="kw">sendCustomMessage</span>(</span>
<span id="cb237-16"><a href="discover.html#cb237-16"></a>    <span class="dt">type =</span> <span class="st">&quot;send-alert&quot;</span>, <span class="dt">message =</span> <span class="st">&quot;Deleting a record!&quot;</span></span>
<span id="cb237-17"><a href="discover.html#cb237-17"></a>  )</span>
<span id="cb237-18"><a href="discover.html#cb237-18"></a></span>
<span id="cb237-19"><a href="discover.html#cb237-19"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>delete_alert, {</span>
<span id="cb237-20"><a href="discover.html#cb237-20"></a>    <span class="co"># print TRUE when button is clicked</span></span>
<span id="cb237-21"><a href="discover.html#cb237-21"></a>    <span class="kw">print</span>(input<span class="op">$</span>delete_alert) </span>
<span id="cb237-22"><a href="discover.html#cb237-22"></a>  })</span>
<span id="cb237-23"><a href="discover.html#cb237-23"></a>}</span>
<span id="cb237-24"><a href="discover.html#cb237-24"></a></span>
<span id="cb237-25"><a href="discover.html#cb237-25"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<pre><code>## [1] TRUE</code></pre>
</div>
<div id="deserialise" class="section level2" number="12.5">
<h2><span class="header-section-number">12.5</span> Deserialise</h2>
<p>In the section on sending data from R to JavaScript we used a “message handler” in JavaScript to handle the data coming from the server. There is also the corollary, an “input handler” to preprocess the data coming from JavaScript before it is made accessible by the input. In R, this is a function that must accept three arguments, the data coming JavaScript, a shiny session, and the name of the input. Note that all of these arguments are mandatory even if they are used in the function.</p>
<p>Input handlers are most often used to reshape or change the type of the data coming in. To demonstrate how use them, we create a handler for the <code>delete_alert</code> which adds somewhat useless meta information to the data.</p>
<div class="sourceCode" id="cb239"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb239-1"><a href="discover.html#cb239-1"></a><span class="co"># create handler</span></span>
<span id="cb239-2"><a href="discover.html#cb239-2"></a>process_input &lt;-<span class="st"> </span><span class="cf">function</span>(x, session, inputname){</span>
<span id="cb239-3"><a href="discover.html#cb239-3"></a>  data &lt;-<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb239-4"><a href="discover.html#cb239-4"></a>    <span class="dt">data =</span> x,</span>
<span id="cb239-5"><a href="discover.html#cb239-5"></a>    <span class="dt">meta =</span> <span class="st">&quot;This is some meta-data&quot;</span></span>
<span id="cb239-6"><a href="discover.html#cb239-6"></a>  )</span>
<span id="cb239-7"><a href="discover.html#cb239-7"></a>  <span class="kw">return</span>(data)</span>
<span id="cb239-8"><a href="discover.html#cb239-8"></a>}</span></code></pre></div>
<p>Once this function created it needs to be registered with shiny using the <code>registerInputHandler</code> function which takes two arguments. First, a unique identifier for the handler, second, the handler function. Attempt to give the handler a unique yet simple name (alphanumeric characters, underscores, and periods) to avoid clashes with other handlers.</p>
<div class="sourceCode" id="cb240"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb240-1"><a href="discover.html#cb240-1"></a><span class="co"># register with shiny</span></span>
<span id="cb240-2"><a href="discover.html#cb240-2"></a><span class="kw">registerInputHandler</span>(<span class="st">&quot;alert.processor&quot;</span>, process_input)</span></code></pre></div>
<p>Note that handlers can only be registered once, running the above twice will fail the second time, even if the handler function has changed. Thus, the handler can be overwritten by setting <code>force</code> to <code>TRUE</code>.</p>
<div class="sourceCode" id="cb241"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb241-1"><a href="discover.html#cb241-1"></a><span class="co"># register with shiny</span></span>
<span id="cb241-2"><a href="discover.html#cb241-2"></a><span class="kw">registerInputHandler</span>(<span class="st">&quot;alert.processor&quot;</span>, process_input, <span class="dt">force =</span> <span class="ot">TRUE</span>)</span></code></pre></div>
<p>Once the handler function created and registered with shiny what is left to do is tell shiny which input should use that handler. This is done by adding the name of the handler, <code>alert.processor</code>, preceded by a colon (<code>:alert.processor</code>) as a suffix to the input name.</p>
<div class="sourceCode" id="cb242"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb242-1"><a href="discover.html#cb242-1"></a><span class="va">Shiny</span>.<span class="at">setInputValue</span>(<span class="st">&#39;delete_alert:alert.processor&#39;</span><span class="op">,</span> <span class="kw">true</span><span class="op">,</span> <span class="op">{</span><span class="dt">priority</span><span class="op">:</span> <span class="st">&#39;event&#39;</span><span class="op">}</span>)<span class="op">;</span></span></code></pre></div>
<p>We can then recap to see what the application would look like now.</p>
<div class="sourceCode" id="cb243"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb243-1"><a href="discover.html#cb243-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb243-2"><a href="discover.html#cb243-2"></a></span>
<span id="cb243-3"><a href="discover.html#cb243-3"></a><span class="co"># create handler</span></span>
<span id="cb243-4"><a href="discover.html#cb243-4"></a>process_input &lt;-<span class="st"> </span><span class="cf">function</span>(x, session, inputname){</span>
<span id="cb243-5"><a href="discover.html#cb243-5"></a>  data &lt;-<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb243-6"><a href="discover.html#cb243-6"></a>    <span class="dt">data =</span> x,</span>
<span id="cb243-7"><a href="discover.html#cb243-7"></a>    <span class="dt">meta =</span> <span class="st">&quot;This is some meta-data&quot;</span></span>
<span id="cb243-8"><a href="discover.html#cb243-8"></a>  )</span>
<span id="cb243-9"><a href="discover.html#cb243-9"></a>  <span class="kw">return</span>(data)</span>
<span id="cb243-10"><a href="discover.html#cb243-10"></a>}</span>
<span id="cb243-11"><a href="discover.html#cb243-11"></a></span>
<span id="cb243-12"><a href="discover.html#cb243-12"></a><span class="co"># register with shiny</span></span>
<span id="cb243-13"><a href="discover.html#cb243-13"></a><span class="kw">registerInputHandler</span>(<span class="st">&quot;alert.processor&quot;</span>, process_input)</span>
<span id="cb243-14"><a href="discover.html#cb243-14"></a></span>
<span id="cb243-15"><a href="discover.html#cb243-15"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb243-16"><a href="discover.html#cb243-16"></a>  tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb243-17"><a href="discover.html#cb243-17"></a>    <span class="st">&quot;Shiny.addCustomMessageHandler(</span></span>
<span id="cb243-18"><a href="discover.html#cb243-18"></a><span class="st">      type = &#39;send-alert&#39;, function(message) {</span></span>
<span id="cb243-19"><a href="discover.html#cb243-19"></a><span class="st">        alert(message);</span></span>
<span id="cb243-20"><a href="discover.html#cb243-20"></a><span class="st">        Shiny.setInputValue(</span></span>
<span id="cb243-21"><a href="discover.html#cb243-21"></a><span class="st">          &#39;delete_alert:alert.processor&#39;, true, </span></span>
<span id="cb243-22"><a href="discover.html#cb243-22"></a><span class="st">          {priority: &#39;event&#39;}</span></span>
<span id="cb243-23"><a href="discover.html#cb243-23"></a><span class="st">        );</span></span>
<span id="cb243-24"><a href="discover.html#cb243-24"></a><span class="st">    });&quot;</span></span>
<span id="cb243-25"><a href="discover.html#cb243-25"></a>  ),</span>
<span id="cb243-26"><a href="discover.html#cb243-26"></a>  <span class="kw">h1</span>(<span class="st">&quot;Hello&quot;</span>)</span>
<span id="cb243-27"><a href="discover.html#cb243-27"></a>)</span>
<span id="cb243-28"><a href="discover.html#cb243-28"></a></span>
<span id="cb243-29"><a href="discover.html#cb243-29"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){</span>
<span id="cb243-30"><a href="discover.html#cb243-30"></a>  session<span class="op">$</span><span class="kw">sendCustomMessage</span>(</span>
<span id="cb243-31"><a href="discover.html#cb243-31"></a>    <span class="dt">type =</span> <span class="st">&quot;send-alert&quot;</span>, <span class="dt">message =</span> <span class="st">&quot;Deleting a record!&quot;</span></span>
<span id="cb243-32"><a href="discover.html#cb243-32"></a>  )</span>
<span id="cb243-33"><a href="discover.html#cb243-33"></a></span>
<span id="cb243-34"><a href="discover.html#cb243-34"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>delete_alert, {</span>
<span id="cb243-35"><a href="discover.html#cb243-35"></a>    <span class="kw">print</span>(input<span class="op">$</span>delete_alert) </span>
<span id="cb243-36"><a href="discover.html#cb243-36"></a>  })</span>
<span id="cb243-37"><a href="discover.html#cb243-37"></a>}</span>
<span id="cb243-38"><a href="discover.html#cb243-38"></a></span>
<span id="cb243-39"><a href="discover.html#cb243-39"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<pre><code>## $data
## [1] TRUE
## 
## $meta
## [1] &quot;This is some meta-data&quot;</code></pre>
<p>The previous section on the input handler is entirely optional but as we will see in later parts of the book it can be nice touch in some cases.</p>

</div>
</div>
<h3>References</h3>
<div id="refs" class="references">
<div id="ref-R-golem">
<p>Guyader, Vincent, Colin Fay, Sébastien Rochette, and Cervan Girard. 2020. <em>Golem: A Framework for Robust Shiny Applications</em>. <a href="https://CRAN.R-project.org/package=golem">https://CRAN.R-project.org/package=golem</a>.</p>
</div>
</div>
            </section>

          </div>
        </div>
      </div>
<a href="excercise-ploty.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="a-complete-integration.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
    </div>
  </div>
<script src="libs/gitbook/js/app.min.js"></script>
<script src="libs/gitbook/js/lunr.js"></script>
<script src="libs/gitbook/js/clipboard.min.js"></script>
<script src="libs/gitbook/js/plugin-search.js"></script>
<script src="libs/gitbook/js/plugin-sharing.js"></script>
<script src="libs/gitbook/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook/js/plugin-bookdown.js"></script>
<script src="libs/gitbook/js/jquery.highlight.js"></script>
<script src="libs/gitbook/js/plugin-clipboard.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"all": {}
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/JohnCoene/javascript-for-r/edit/master/4-11-shiny-first-look.Rmd",
"text": "Edit"
},
"history": {
"link": null,
"text": null
},
"view": {
"link": null,
"text": null
},
"download": {},
"toc": {
"collapse": "section"
}
});
});
</script>

</body>

</html>
